package com.tanhua.manager.service;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.alibaba.fastjson.JSON;
import com.tanhua.domain.db.Admin;
import com.tanhua.dubbo.api.db.AdminApi;
import com.tanhua.manager.exceptions.TanhuaException;
import com.tanhua.manager.interceptors.AdminHolder;
import com.tanhua.manager.utils.JwtUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AdminService {

    @Autowired
    private StringRedisTemplate redisTemplate;


//    存储token的前缀
    private static final String CACHE_KEY_TOKEN_PREFIX="MANAGE_TOKEN_";
//  存储验证码的前缀
    private static final String CACHE_KEY_CAP_PREFIX = "MANAGE_CAP_";


    //根据登录token，获取用户对象
    public Admin findAdminByToken(String token) {
        String adminStr = redisTemplate.boundValueOps(CACHE_KEY_TOKEN_PREFIX+token).get();
        if(adminStr == null) {
            return null;
        }
        redisTemplate.boundValueOps(CACHE_KEY_TOKEN_PREFIX+token).set(adminStr,2, TimeUnit.HOURS);//续期
        return JSON.parseObject(adminStr,Admin.class);
    }


    /**
     * 从redis中删除token缓存
     */
    public void removeToken(String token){
        String redisTokenKey = CACHE_KEY_TOKEN_PREFIX + token;
        this.redisTemplate.delete(redisTokenKey);
    }

    public ResponseEntity verification(String uuid, HttpServletResponse response) throws Exception {
//        生成一张有内容的图片
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(300, 100);
        lineCaptcha.write(response.getOutputStream());

//        获取到验证码内容 存储到redis中 为了以后的验证
        String code = lineCaptcha.getCode();
        redisTemplate.boundValueOps(CACHE_KEY_CAP_PREFIX+uuid).set(code,10,TimeUnit.MINUTES);

        return ResponseEntity.ok(null);

    }

    @Reference
    private AdminApi adminApi;

    public ResponseEntity login(String username, String password, String verificationCode, String uuid) {
//        1、用户名和密码做非空判断
        if(StringUtils.isBlank(username)||StringUtils.isBlank(password)){
            throw new TanhuaException(500,"用户名或密码不能为空");
        }

//        2、判断是否能从redis中获取验证码
        String code = redisTemplate.boundValueOps(CACHE_KEY_CAP_PREFIX + uuid).get();
        if(StringUtils.isBlank(code)){
            throw new TanhuaException(500,"请重新获取验证码");
        }
//        3、判断两个验证码是否一致
        if(!StringUtils.equals(verificationCode,code)){
            throw new TanhuaException(500,"验证码错误");
        }

//        4、根据用户名查询Admin
        Admin admin = adminApi.findByUsername(username);
//        5、判断是否能查到Admin
        if(admin==null){
            throw new TanhuaException(500,"用户名有误");
        }
//        6、判断密码  把手动输入的密码加密 再和表中的密码比较
        String password_page = DigestUtils.md5Hex(password);
        String password_db = admin.getPassword();
        if(!StringUtils.equals(password_page,password_db)){
            throw new TanhuaException(500,"密码错误");
        }

//        7、生成token放到redis中
        String token = JwtUtils.createToken(username, admin.getId(), "class145");
        String adminStr = JSON.toJSONString(admin);
        redisTemplate.boundValueOps(CACHE_KEY_TOKEN_PREFIX+token).set(adminStr,2, TimeUnit.HOURS);//续期
//        8、把token放到一个对象中返回
//        {token:13erfwefsdcsdvcs}

        Map result = new HashMap();
        result.put("token",token);
        return ResponseEntity.ok(result);

    }

    public ResponseEntity logout() {

        Admin admin = AdminHolder.getAdmin();
//        清除redis中的token
        redisTemplate.delete(CACHE_KEY_TOKEN_PREFIX + admin.getToken());

        return ResponseEntity.ok(null);
    }

    public void saveTokenToRedis(Admin admin) {
        //        7、生成token放到redis中
        String adminStr = JSON.toJSONString(admin);
        redisTemplate.boundValueOps(CACHE_KEY_TOKEN_PREFIX+admin.getToken()).set(adminStr,2, TimeUnit.HOURS);//续期
    }
}